home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / news / inn1.000 / inn1.4sec-linux-src.tar / inn / lib / qio.c < prev    next >
C/C++ Source or Header  |  1992-07-24  |  4KB  |  202 lines

  1. /*  $Revision: 1.9 $
  2. **
  3. **  Quick I/O package -- optimized for reading through a file.
  4. */
  5. #include "configdata.h"
  6. #include <stdio.h>
  7. #include <fcntl.h>
  8. #include <ctype.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <errno.h>
  12. #include "libinn.h"
  13. #include "clibrary.h"
  14. #include "qio.h"
  15. #include "macros.h"
  16.  
  17.  
  18. /*
  19. **  Open a quick file from a descriptor.
  20. */
  21. QIOSTATE *
  22. QIOfdopen(fd, size)
  23.     int        fd;
  24.     int        size;
  25. {
  26.     QIOSTATE    *qp;
  27. #if    defined(DO_HAVE_ST_BLKSIZE)
  28.     struct stat    Sb;
  29. #endif    /* defined(DO_HAVE_ST_BLKSIZE) */
  30.  
  31.     qp = NEW(QIOSTATE, 1);
  32.     qp->flag = QIO_ok;
  33.     qp->fd = fd;
  34. #if    defined(DO_HAVE_ST_BLKSIZE)
  35.     if (size == 0)
  36.     size = fstat(fd, &Sb) >= 0 ? (int)Sb.st_blksize : QIO_BUFFER;
  37. #else
  38.     if (size == 0)
  39.     size = QIO_BUFFER;
  40. #endif    /* defined(DO_HAVE_ST_BLKSIZE) */
  41.     qp->Size = size;
  42.     qp->Buffer = NEW(char, size);
  43.     qp->Count = 0;
  44.     qp->Start = qp->Buffer;
  45.     qp->End = qp->Buffer;
  46.  
  47.     return qp;
  48. }
  49.  
  50.  
  51. /*
  52. **  Open a file for reading.
  53. */
  54. QIOSTATE *
  55. QIOopen(name, size)
  56.     char    *name;
  57.     int        size;
  58. {
  59.     int        fd;
  60.  
  61.     /* Open the file, read in the first chunk. */
  62.     if ((fd = open(name, O_RDONLY)) < 0)
  63.     return NULL;
  64.     return QIOfdopen(fd, size);
  65. }
  66.  
  67.  
  68. /*
  69. **  Close an open stream.
  70. */
  71. void
  72. QIOclose(qp)
  73.     QIOSTATE    *qp;
  74. {
  75.     (void)close(qp->fd);
  76.     DISPOSE(qp->Buffer);
  77.     DISPOSE(qp);
  78. }
  79.  
  80.  
  81. /*
  82. **  Rewind an open stream.
  83. */
  84. int
  85. QIOrewind(qp)
  86.     QIOSTATE    *qp;
  87. {
  88.     int        i;
  89.  
  90.     if (lseek(qp->fd, 0L, SEEK_SET) == -1)
  91.     return -1;
  92.     i = read(qp->fd, qp->Buffer, (SIZE_T)qp->Size);
  93.     if (i < 0)
  94.     return i;
  95.     qp->Count = i;
  96.     qp->Start = qp->Buffer;
  97.     qp->End = &qp->Buffer[i];
  98.     return 0;
  99. }
  100.  
  101.  
  102. /*
  103. **  Get the next line from the input.
  104. */
  105. char *
  106. QIOread(qp)
  107.     QIOSTATE    *qp;
  108. {
  109.     register char    *p;
  110.     register char    *q;
  111.     char        *save;
  112.     int            i;
  113.  
  114.     /* Read from buffer if there is any data there. */
  115.     if (qp->End > qp->Start) {
  116.  
  117.     /* Find the newline. */
  118.     p = memchr((POINTER)qp->Start, '\n', (SIZE_T)(qp->End - qp->Start));
  119.     if (p != NULL) {
  120.         *p = '\0';
  121.         qp->Length = p - qp->Start;
  122.         save = qp->Start;
  123.         qp->Start = p + 1;
  124.         qp->flag = QIO_ok;
  125.         return save;
  126.     }
  127.  
  128.     /* Not there; move unread part down to start of buffer. */
  129.     for (p = qp->Buffer, q = qp->Start; q < qp->End; )
  130.         *p++ = *q++;
  131.     }
  132.     else
  133.     p = qp->Buffer;
  134.  
  135.     /* Read data, reset the pointers. */
  136.     i = read(qp->fd, p, (SIZE_T)(&qp->Buffer[qp->Size] - p));
  137.     if (i < 0) {
  138.     qp->flag = QIO_error;
  139.     return NULL;
  140.     }
  141.     if (i == 0) {
  142.     qp->flag = QIO_ok;
  143.     return NULL;
  144.     }
  145.     qp->Count += i;
  146.     qp->Start = qp->Buffer;
  147.     qp->End = &p[i];
  148.  
  149.     /* Now try to find it. */
  150.     p = memchr((POINTER)qp->Start, '\n', (SIZE_T)(qp->End - qp->Start));
  151.     if (p != NULL) {
  152.     *p = '\0';
  153.     qp->Length = p - qp->Start;
  154.     save = qp->Start;
  155.     qp->Start = p + 1;
  156.     qp->flag = QIO_ok;
  157.     return save;
  158.     }
  159.  
  160.     /* Still not there -- line is too long. */
  161.     qp->flag = QIO_long;
  162.     qp->Start = qp->End;
  163.     return NULL;
  164. }
  165.  
  166.  
  167.  
  168. #if    defined(TEST)
  169. int
  170. main(ac, av)
  171.     int        ac;
  172.     char    *av[];
  173. {
  174.     QIOSTATE    *h;
  175.     char    *p;
  176.     long    where;
  177.  
  178.     h = QIOopen(ac > 1 ? av[1] : "/usr/lib/news/history", 0);
  179.     if (h == NULL) {
  180.     perror("Can't open file");
  181.     exit(1);
  182.     }
  183.  
  184.     where = QIOtell(h);
  185.     while ((p = QIOread(h)) != NULL) {
  186.     printf("%5ld %3d %s\n", where, QIOlength(h), p);
  187.     where = QIOtell(h);
  188.     }
  189.     if (QIOtoolong(h)) {
  190.     fprintf(stderr, "Line too line at %ld\n", QIOtell(h));
  191.     exit(1);
  192.     }
  193.     if (QIOerror(h)) {
  194.     perror("Can't read");
  195.     exit(1);
  196.     }
  197.     QIOclose(h);
  198.     exit(0);
  199.     /* NOTREACHED */
  200. }
  201. #endif    /* defined(TEST) */
  202.